package com.ihr360.payroll.service.payroll.mock.core;

import com.google.common.collect.ImmutableList;
import com.ihr360.commons.model.meta.table.DynamicCell;
import com.ihr360.commons.model.type.TaxRole;
import com.ihr360.expr.ExprArray;
import com.ihr360.expr.engine.EngineProvider;
import com.ihr360.job.core.item.support.MapMapItemWriter;
import com.ihr360.job.core.item.support.OneShotItemWriter;
import com.ihr360.payperiod.PayPeriodTerm;
import com.ihr360.payroll.calc.StaffSalaryCalcPeriod;
import com.ihr360.payroll.config.SalaryTaxEntity;
import com.ihr360.payroll.config.SalaryTaxRuleEntity;
import com.ihr360.payroll.config.SalaryTaxTableEntity;
import com.ihr360.payroll.config.TaxDivisionEntity;
import com.ihr360.payroll.model.dto.attendance.plan.AttendancePlan;
import com.ihr360.payroll.model.dto.salary.meta.SalaryField;
import com.ihr360.payroll.service.salarytasklet.dao.AttendancePlanDao;
import com.ihr360.payroll.service.salarytasklet.expr.engine.SalaryDependencyEngine;
import com.ihr360.payroll.service.salarytasklet.expr.engine.SalaryExprEngineProvider;
import com.ihr360.payroll.service.salarytasklet.model.SimplePayrollConfig;
import com.ihr360.payroll.service.salarytasklet.step.SalaryCalcContext;
import com.ihr360.payroll.service.salarytasklet.step.SystemCalcContext;
import com.ihr360.payroll.service.salarytasklet.step.processor.AttendancePlanDependencyProcessor;
import com.ihr360.payroll.service.salarytasklet.step.processor.PayrollConfigProcessor;
import com.ihr360.payroll.service.salarytasklet.step.processor.SalaryFieldDependencyProcessor;
import com.ihr360.payroll.service.salarytasklet.step.processor.TaxTableProcessor;
import com.ihr360.sharedservice.model.StatutoryVacation;
import com.ihr360.sharedservice.model.VacationCategory;
import com.ihr360.sharedservice.model.WorkingCalendar;
import org.junit.Assert;
import org.springframework.data.util.Pair;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public abstract class MockPersonalSalaryCalcCapable implements PersonalSalaryCalcCapable{


    @Override
    public SalaryCalcContext buildContext() throws Exception {
        SalaryCalcContext context = new SalaryCalcContext();
        SystemCalcContext systemCalcContext = new SystemCalcContext();
        context.systemCalcContext = systemCalcContext;

        context.attendancePlanHolder = attendancePlanHolder();
        context.salaryFieldsHolder = salaryFieldWriter(context);
        context.dependencyEngineHolder = dependencyEngineHolder();
        context.taxTableHolder = taxTableHolder();
        context.payPeriodTerm = new PayPeriodTerm();
        processSalaryFieldDependency(context);

        processAttendancePlanDependency(context);

//        ExprArray taxTable = TaxTableHelper.getSalaryTaxTable();
//        ExprArray bonusTaxTable = TaxTableHelper.getYearEndBonusTaxTable();
//        context.dependencyEngineHolder.getWrittenItem().getProvider().addVariable("$TAX_TABLE$salary_tax", taxTable);
//        context.dependencyEngineHolder.getWrittenItem().getProvider().addVariable("$TAX_TABLE$annual_bonus_tax", bonusTaxTable);
        return context;
    }

//    public void clearEngine(SalaryCalcContext context){
//        SalaryDependencyEngine dependencyEngine = context.dependencyEngineHolder.getWrittenItem();
//        if (dependencyEngine!=null){
//            dependencyEngine.clear();
//        }
//    }

    @Override
    public void processSalaryFieldDependency(SalaryCalcContext context) throws Exception {
        SalaryFieldDependencyProcessor processor = new SalaryFieldDependencyProcessor();
        processor.setJobRepository(new JobRepositoryMock());
        processor.process(context);
    }

    @Override
    public void processAttendancePlanDependency(SalaryCalcContext context) throws Exception {
        AttendancePlanDependencyProcessor processor = new AttendancePlanDependencyProcessor();
        processor.setJobRepository(new JobRepositoryMock());
        processor.setAttendancePlanDao(new AttendancePlanDao() {
            @Override
            public AttendancePlan findOne(Long id) {
                return getAttendanceHelper();
            }
        });
        processor.process(context);
    }


    @Override
    public SimplePayrollConfig buildPayrollConfig() {
        SimplePayrollConfig payrollConfig = new SimplePayrollConfig(null,null,SalaryFieldHelper.salaryFieldList());
        return payrollConfig;
    }


    @Override
    public OneShotItemWriter<Map<String, SalaryField>> salaryFieldWriter(SalaryCalcContext context) throws Exception {
        PayrollConfigProcessor processor = new PayrollConfigProcessor();
        processor.setSalaryCalcContext(context);
        processor.setJobRepository(new JobRepositoryMock());
        Map<String, SalaryField> fieldMap = processor.process(buildPayrollConfig());

        OneShotItemWriter<Map<String, SalaryField>> salaryFieldWriter = new OneShotItemWriter<>();
        salaryFieldWriter.write(ImmutableList.of(fieldMap));
        return salaryFieldWriter;
    }

    @Override
    public OneShotItemWriter<SalaryDependencyEngine> dependencyEngineHolder() throws Exception {
        EngineProvider engineProvider = new SalaryExprEngineProvider();
        SalaryDependencyEngine dependencyEngine = new SalaryDependencyEngine(engineProvider);
        OneShotItemWriter<SalaryDependencyEngine> writer = new OneShotItemWriter<>();
        writer.write(ImmutableList.of(dependencyEngine));
        return writer;
    }

    @Override
    public OneShotItemWriter<AttendancePlan> attendancePlanHolder() throws Exception {
        AttendancePlan plan = getAttendanceHelper();
        OneShotItemWriter<AttendancePlan> writer = new OneShotItemWriter<>();
        writer.write(ImmutableList.of(plan));
        return writer;
    }

    @Override
    public MapMapItemWriter<String, Map<String, ExprArray>> taxTableHolder() throws Exception {
        MapMapItemWriter<String, Map<String, ExprArray>> writer = new MapMapItemWriter<>();
        writer.write(ImmutableList.of(
                buildTaxTable(),
                buildForeignSalaryTaxTable(),
                buildAnnualBonusTaxTable(),
                buildAnnualBonusTaxTable4Foreign()));
        return writer;
    }

    @Override
    public TaxDivisionEntity ZHCNTaxDivision() {
        TaxDivisionEntity taxDivision = new TaxDivisionEntity();
        taxDivision.setCode("ZHCN");
        return taxDivision;
    }


    @Override
    public Pair<String, Map<String, ExprArray>> buildAnnualBonusTaxTable() throws Exception {
        TaxTableProcessor processor = new TaxTableProcessor(salaryPeriodMonth());
        SalaryTaxTableEntity taxTable = new SalaryTaxTableEntity();

        taxTable.setDivision(ZHCNTaxDivision());

        taxTable.setTaxRole(TaxRole.NATIVE);

        taxTable.setType(TaxTypeHelper.annualBonusTaxTypeEntity());

        SalaryTaxEntity tax = new SalaryTaxEntity();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, 2010);
        tax.setEffectiveAt(calendar.getTime());
        tax.setInvalidAt(null);

        SalaryTaxRuleEntity rule0 = new SalaryTaxRuleEntity();
        rule0.setCeil(0l);
        rule0.setExamption(0l);
        rule0.setFixed(true);
        rule0.setFloor(0l);
        rule0.setRatio(0);
        rule0.setReduce(0);
        rule0.setTaxCeil(0l);
        rule0.setTaxFloor(0l);

        SalaryTaxRuleEntity rule = new SalaryTaxRuleEntity();
        rule.setCeil(150000l);
        rule.setExamption(0l);
        rule.setFixed(true);
        rule.setFloor(0l);
        rule.setRatio(300);
        rule.setReduce(0);
        rule.setTaxCeil(150000l);
        rule.setTaxFloor(0l);

        SalaryTaxRuleEntity rule1 = new SalaryTaxRuleEntity();
        rule1.setCeil(450000l);
        rule1.setExamption(0l);
        rule1.setFixed(true);
        rule1.setFloor(150000l);
        rule1.setRatio(1000);
        rule1.setReduce(10500);
        rule1.setTaxCeil(450000l);
        rule1.setTaxFloor(150000l);


        SalaryTaxRuleEntity rule2 = new SalaryTaxRuleEntity();
        rule2.setCeil(900000l);
        rule2.setExamption(0l);
        rule2.setFixed(true);
        rule2.setFloor(450000l);
        rule2.setRatio(2000);
        rule2.setReduce(55500);
        rule2.setTaxCeil(900000l);
        rule2.setTaxFloor(450000l);

        SalaryTaxRuleEntity rule3 = new SalaryTaxRuleEntity();
        rule3.setCeil(3500000l);
        rule3.setExamption(0l);
        rule3.setFixed(true);
        rule3.setFloor(900000l);
        rule3.setRatio(2500);
        rule3.setReduce(100500);
        rule3.setTaxCeil(3500000l);
        rule3.setTaxFloor(900000l);

        SalaryTaxRuleEntity rule4 = new SalaryTaxRuleEntity();
        rule4.setCeil(5500000l);
        rule4.setExamption(0l);
        rule4.setFixed(true);
        rule4.setFloor(3500000l);
        rule4.setRatio(3000);
        rule4.setReduce(275500);
        rule4.setTaxCeil(5500000l);
        rule4.setTaxFloor(3500000l);

        SalaryTaxRuleEntity rule5 = new SalaryTaxRuleEntity();
        rule5.setCeil(8000000l);
        rule5.setExamption(0l);
        rule5.setFixed(true);
        rule5.setFloor(5500000l);
        rule5.setRatio(3500);
        rule5.setReduce(550500);
        rule5.setTaxCeil(8000000l);
        rule5.setTaxFloor(5500000l);

        SalaryTaxRuleEntity rule6 = new SalaryTaxRuleEntity();
        rule6.setCeil(null);
        rule6.setExamption(0l);
        rule6.setFixed(true);
        rule6.setFloor(8000000l);
        rule6.setRatio(4500);
        rule6.setReduce(1350500);
        rule6.setTaxCeil(null);
        rule6.setTaxFloor(8000000l);

        tax.setRules(ImmutableList.of(rule0, rule, rule1, rule2, rule3, rule4, rule5, rule6));

        taxTable.setSalaryTaxes(ImmutableList.of(tax));
        return processor.process(taxTable);
    }

    @Override
    public Pair<String, Map<String, ExprArray>> buildAnnualBonusTaxTable4Foreign() throws Exception {
        TaxTableProcessor processor = new TaxTableProcessor(salaryPeriodMonth());
        SalaryTaxTableEntity taxTable = new SalaryTaxTableEntity();

        taxTable.setDivision(ZHCNTaxDivision());

        taxTable.setTaxRole(TaxRole.FOREIGN);

        taxTable.setType(TaxTypeHelper.annualBonusTaxTypeEntity());

        SalaryTaxEntity tax = new SalaryTaxEntity();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, 2010);
        tax.setEffectiveAt(calendar.getTime());
        tax.setInvalidAt(null);

        SalaryTaxRuleEntity rule0 = new SalaryTaxRuleEntity();
        rule0.setCeil(0l);
        rule0.setExamption(0l);
        rule0.setFixed(true);
        rule0.setFloor(0l);
        rule0.setRatio(0);
        rule0.setReduce(0);
        rule0.setTaxCeil(0l);
        rule0.setTaxFloor(0l);

        SalaryTaxRuleEntity rule1 = new SalaryTaxRuleEntity();
        rule1.setCeil(150000l);
        rule1.setExamption(0l);
        rule1.setFixed(true);
        rule1.setFloor(0l);
        rule1.setRatio(300);
        rule1.setReduce(0);
        rule1.setTaxCeil(150000l);
        rule1.setTaxFloor(0l);

        SalaryTaxRuleEntity rule2 = new SalaryTaxRuleEntity();
        rule2.setCeil(450000l);
        rule2.setExamption(0l);
        rule2.setFixed(true);
        rule2.setFloor(150000l);
        rule2.setRatio(1000);
        rule2.setReduce(10500);
        rule2.setTaxCeil(450000l);
        rule2.setTaxFloor(150000l);


        SalaryTaxRuleEntity rule3 = new SalaryTaxRuleEntity();
        rule3.setCeil(900000l);
        rule3.setExamption(0l);
        rule3.setFixed(true);
        rule3.setFloor(450000l);
        rule3.setRatio(2000);
        rule3.setReduce(55500);
        rule3.setTaxCeil(900000l);
        rule3.setTaxFloor(450000l);

        SalaryTaxRuleEntity rule4 = new SalaryTaxRuleEntity();
        rule4.setCeil(3500000l);
        rule4.setExamption(0l);
        rule4.setFixed(true);
        rule4.setFloor(900000l);
        rule4.setRatio(2500);
        rule4.setReduce(100500);
        rule4.setTaxCeil(3500000l);
        rule4.setTaxFloor(900000l);

        SalaryTaxRuleEntity rule5 = new SalaryTaxRuleEntity();
        rule5.setCeil(5500000l);
        rule5.setExamption(0l);
        rule5.setFixed(true);
        rule5.setFloor(3500000l);
        rule5.setRatio(3000);
        rule5.setReduce(275500);
        rule5.setTaxCeil(5500000l);
        rule5.setTaxFloor(3500000l);

        SalaryTaxRuleEntity rule6 = new SalaryTaxRuleEntity();
        rule6.setCeil(8000000l);
        rule6.setExamption(0l);
        rule6.setFixed(true);
        rule6.setFloor(5500000l);
        rule6.setRatio(3500);
        rule6.setReduce(550500);
        rule6.setTaxCeil(8000000l);
        rule6.setTaxFloor(5500000l);

        SalaryTaxRuleEntity rule7 = new SalaryTaxRuleEntity();
        rule7.setCeil(null);
        rule7.setExamption(0l);
        rule7.setFixed(true);
        rule7.setFloor(8000000l);
        rule7.setRatio(4500);
        rule7.setReduce(1350500);
        rule7.setTaxCeil(null);
        rule7.setTaxFloor(8000000l);

        tax.setRules(ImmutableList.of(rule0, rule1, rule2, rule3, rule4, rule5, rule6, rule7));

        taxTable.setSalaryTaxes(ImmutableList.of(tax));
        return processor.process(taxTable);
    }

    @Override
    public Pair<String, Map<String, ExprArray>> buildTaxTable() throws Exception {
        TaxTableProcessor processor = new TaxTableProcessor(salaryPeriodMonth());
        SalaryTaxTableEntity taxTable = new SalaryTaxTableEntity();

        taxTable.setDivision(ZHCNTaxDivision());

        taxTable.setTaxRole(TaxRole.NATIVE);

        taxTable.setType(TaxTypeHelper.salaryTaxTypeEntity());

        SalaryTaxEntity tax = new SalaryTaxEntity();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, 2010);
        tax.setEffectiveAt(calendar.getTime());
        tax.setInvalidAt(null);

        SalaryTaxRuleEntity rule0 = new SalaryTaxRuleEntity();
        rule0.setCeil(0L);
        rule0.setExamption(350000L);
        rule0.setFixed(true);
        rule0.setFloor(0L);
        rule0.setRatio(0);
        rule0.setReduce(0);
        rule0.setTaxCeil(0L);
        rule0.setTaxFloor(0L);

        SalaryTaxRuleEntity rule1 = new SalaryTaxRuleEntity();
        rule1.setCeil(500000L);
        rule1.setExamption(350000L);
        rule1.setFixed(true);
        rule1.setFloor(350000L);
        rule1.setRatio(300);
        rule1.setReduce(0);
        rule1.setTaxCeil(150000L);
        rule1.setTaxFloor(0L);

        SalaryTaxRuleEntity rule2 = new SalaryTaxRuleEntity();
        rule2.setCeil(800000L);
        rule2.setExamption(350000L);
        rule2.setFixed(true);
        rule2.setFloor(500000L);
        rule2.setRatio(1000);
        rule2.setReduce(10500);
        rule2.setTaxCeil(450000L);
        rule2.setTaxFloor(150000L);


        SalaryTaxRuleEntity rule3 = new SalaryTaxRuleEntity();
        rule3.setCeil(1250000L);
        rule3.setExamption(350000L);
        rule3.setFixed(true);
        rule3.setFloor(800000L);
        rule3.setRatio(2000);
        rule3.setReduce(55500);
        rule3.setTaxCeil(900000L);
        rule3.setTaxFloor(450000L);

        SalaryTaxRuleEntity rule4 = new SalaryTaxRuleEntity();
        rule4.setCeil(3850000L);
        rule4.setExamption(350000L);
        rule4.setFixed(true);
        rule4.setFloor(1250000L);
        rule4.setRatio(2500);
        rule4.setReduce(100500);
        rule4.setTaxCeil(3500000L);
        rule4.setTaxFloor(900000L);

        SalaryTaxRuleEntity rule5 = new SalaryTaxRuleEntity();
        rule5.setCeil(5850000L);
        rule5.setExamption(350000L);
        rule5.setFixed(true);
        rule5.setFloor(3850000L);
        rule5.setRatio(3000);
        rule5.setReduce(275500);
        rule5.setTaxCeil(5500000L);
        rule5.setTaxFloor(3500000L);

        SalaryTaxRuleEntity rule6 = new SalaryTaxRuleEntity();
        rule6.setCeil(8350000L);
        rule6.setExamption(350000L);
        rule6.setFixed(true);
        rule6.setFloor(5850000L);
        rule6.setRatio(3500);
        rule6.setReduce(550500);
        rule6.setTaxCeil(8000000L);
        rule6.setTaxFloor(5500000L);

        SalaryTaxRuleEntity rule7 = new SalaryTaxRuleEntity();
        rule7.setCeil(null);
        rule7.setExamption(350000L);
        rule7.setFixed(true);
        rule7.setFloor(5850000L);
        rule7.setRatio(4500);
        rule7.setReduce(1350500);
        rule7.setTaxCeil(null);
        rule7.setTaxFloor(8000000L);


        tax.setRules(ImmutableList.of(rule0, rule1, rule2, rule3, rule4, rule5, rule6, rule7));

        taxTable.setSalaryTaxes(ImmutableList.of(tax));
        return processor.process(taxTable);
    }

    @Override
    public Pair<String, Map<String, ExprArray>> buildForeignSalaryTaxTable() throws Exception {
        TaxTableProcessor processor = new TaxTableProcessor(salaryPeriodMonth());
        SalaryTaxTableEntity taxTable = new SalaryTaxTableEntity();
        TaxDivisionEntity taxDivision = new TaxDivisionEntity();
        taxDivision.setCode("ZHCN");
        taxTable.setDivision(taxDivision);
        taxTable.setTaxRole(TaxRole.FOREIGN);

        taxTable.setType(TaxTypeHelper.salaryTaxTypeEntity());

        SalaryTaxEntity tax = new SalaryTaxEntity();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, 2010);
        tax.setEffectiveAt(calendar.getTime());
        tax.setInvalidAt(null);


        SalaryTaxRuleEntity rule0 = new SalaryTaxRuleEntity();
        rule0.setCeil(0l);
        rule0.setExamption(480000l);
        rule0.setFixed(true);
        rule0.setFloor(0l);
        rule0.setRatio(0);
        rule0.setReduce(0);
        rule0.setTaxCeil(0l);
        rule0.setTaxFloor(0l);

        SalaryTaxRuleEntity rule = new SalaryTaxRuleEntity();
        rule.setCeil(630000l);
        rule.setExamption(480000l);
        rule.setFixed(true);
        rule.setFloor(480000l);
        rule.setRatio(300);
        rule.setReduce(0);
        rule.setTaxCeil(150000l);
        rule.setTaxFloor(0l);

        SalaryTaxRuleEntity rule1 = new SalaryTaxRuleEntity();
        rule1.setCeil(930000l);
        rule1.setExamption(480000l);
        rule1.setFixed(true);
        rule1.setFloor(630000l);
        rule1.setRatio(1000);
        rule1.setReduce(10500);
        rule1.setTaxCeil(450000l);
        rule1.setTaxFloor(150000l);


        SalaryTaxRuleEntity rule2 = new SalaryTaxRuleEntity();
        rule2.setCeil(1380000l);
        rule2.setExamption(480000l);
        rule2.setFixed(true);
        rule2.setFloor(930000l);
        rule2.setRatio(2000);
        rule2.setReduce(55500);
        rule2.setTaxCeil(900000l);
        rule2.setTaxFloor(450000l);

        SalaryTaxRuleEntity rule3 = new SalaryTaxRuleEntity();
        rule3.setCeil(3980000l);
        rule3.setExamption(480000l);
        rule3.setFixed(true);
        rule3.setFloor(138000l);
        rule3.setRatio(2500);
        rule3.setReduce(100500);
        rule3.setTaxCeil(3500000l);
        rule3.setTaxFloor(900000l);

        SalaryTaxRuleEntity rule4 = new SalaryTaxRuleEntity();
        rule4.setCeil(5980000l);
        rule4.setExamption(480000l);
        rule4.setFixed(true);
        rule4.setFloor(3980000l);
        rule4.setRatio(3000);
        rule4.setReduce(275500);
        rule4.setTaxCeil(5500000l);
        rule4.setTaxFloor(3500000l);

        SalaryTaxRuleEntity rule5 = new SalaryTaxRuleEntity();
        rule5.setCeil(8480000l);
        rule5.setExamption(480000l);
        rule5.setFixed(true);
        rule5.setFloor(5980000l);
        rule5.setRatio(3500);
        rule5.setReduce(550500);
        rule5.setTaxCeil(8000000l);
        rule5.setTaxFloor(5500000l);

        tax.setRules(ImmutableList.of(rule0, rule, rule1, rule2, rule3, rule4, rule5));

        taxTable.setSalaryTaxes(ImmutableList.of(tax));
        return processor.process(taxTable);
    }


    @Override
    public StaffSalaryCalcPeriod buildSalaryCalcPeriod() {
        StaffSalaryCalcPeriod salaryCalcPeriod = new StaffSalaryCalcPeriod(staffId(), staffName());
        return salaryCalcPeriod;
    }

    @Override
    public OneShotItemWriter<WorkingCalendar> workingCalendarHolderOfMarch() throws Exception {
        OneShotItemWriter<WorkingCalendar> workingCalendarOneShotItemWriter = new OneShotItemWriter<>();
        workingCalendarOneShotItemWriter.write(ImmutableList.of(buildWorkingCalendar201803()));
        return workingCalendarOneShotItemWriter;
    }


    private WorkingCalendar buildWorkingCalendar201802() {
        Map<Date, StatutoryVacation> holidayCalendar = new HashMap<>();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, 1);
        calendar.set(Calendar.DATE, 11);
        holidayCalendar.put(calendar.getTime(), new StatutoryVacation(calendar.getTime(), VacationCategory.SUPPLEMENTARY, false));
        calendar.set(Calendar.DATE, 15);
        holidayCalendar.put(calendar.getTime(), new StatutoryVacation(calendar.getTime(), VacationCategory.STATUTORY, false));
        calendar.set(Calendar.DATE, 16);
        holidayCalendar.put(calendar.getTime(), new StatutoryVacation(calendar.getTime(), VacationCategory.STATUTORY, true));
        calendar.set(Calendar.DATE, 17);
        holidayCalendar.put(calendar.getTime(), new StatutoryVacation(calendar.getTime(), VacationCategory.STATUTORY, true));
        calendar.set(Calendar.DATE, 18);
        holidayCalendar.put(calendar.getTime(), new StatutoryVacation(calendar.getTime(), VacationCategory.STATUTORY, true));
        calendar.set(Calendar.DATE, 19);
        holidayCalendar.put(calendar.getTime(), new StatutoryVacation(calendar.getTime(), VacationCategory.STATUTORY, false));
        calendar.set(Calendar.DATE, 20);
        holidayCalendar.put(calendar.getTime(), new StatutoryVacation(calendar.getTime(), VacationCategory.STATUTORY, false));
        calendar.set(Calendar.DATE, 21);
        holidayCalendar.put(calendar.getTime(), new StatutoryVacation(calendar.getTime(), VacationCategory.STATUTORY, false));
        calendar.set(Calendar.DATE, 24);
        holidayCalendar.put(calendar.getTime(), new StatutoryVacation(calendar.getTime(), VacationCategory.SUPPLEMENTARY, false));

        WorkingCalendar workingCalendar = new WorkingCalendar( holidayCalendar);
        return workingCalendar;
    }

    @Override
    public WorkingCalendar buildWorkingCalendar201803() {
        Map<Date, StatutoryVacation> holidayCalendar = new HashMap<>();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, 2);
        calendar.set(Calendar.DATE, 1);
        WorkingCalendar workingCalendar = new WorkingCalendar(holidayCalendar);
        return workingCalendar;
    }

    @Override
    public void fieldAssertEquals(String field, String expected) {
        Map<String, DynamicCell> data = MockPersonalSalaryCalcContextHolder.getCurrentCalcdResult().getSummarizedData();
        DynamicCell cell = data.get(field);
        if (cell != null) {
            Assert.assertEquals(field, expected, cell.getCellValue());
        } else {
            Assert.assertEquals(field, expected, "0.0");
        }
    }

    @Override
    public AttendancePlan getAttendanceHelper() {
        return AttendancePlanHelper.attendancePlan();
    }


    @Override
    public Date salaryPeriodMonth() {
        return new Date();
    }
}
